﻿using Apewer;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;

namespace Apewer
{

    /// <summary></summary>
    [Serializable]
    public sealed class StringPairs : List<KeyValuePair<string, string>>, IToJson
    {

        /// <summary>使用 key 选择器时忽略大小写。</summary>
        /// <remarks>默认值：true</remarks>
        public bool IngoreCase { get; set; }

        /// <summary></summary>
        public StringPairs() : base()
        {
            IngoreCase = true;
        }

        /// <summary></summary>
        public StringPairs(int capacity) : base(capacity)
        {
            IngoreCase = true;
        }

        /// <summary></summary>
        public string this[string key]
        {
            get { return GetValue(key); }
            set { SetValue(key, value, true); }
        }

        /// <summary>添加项。返回错误信息。</summary>
        public string Add(string key, string value)
        {
            if (string.IsNullOrEmpty(key)) return "参数 Key 无效。";
            // if (string.IsNullOrEmpty(value)) return "参数 Value 无效。";

            var kvp = new KeyValuePair<string, string>(key, value);
            Add(kvp);
            return null;
        }

        /// <summary>获取所有 Key。</summary>
        public string[] GetAllKeys()
        {
            var keys = new string[Count];
            for (var i = 0; i < Count; i++) keys[i] = this[i].Key;
            return keys;
        }

        /// <summary>获取匹配 Key 的所有 Value，不存在 Key 或 Value 时返回空数组。</summary>
        public string[] GetValues(string key, bool ignoreCase = true, bool withEmpty = true)
        {
            if (string.IsNullOrEmpty(key)) return new string[0];

            var lowerArg = TextUtility.Lower(key);
            var values = new List<string>();
            foreach (var item in this)
            {
                if (item.Key == key)
                {
                    if (withEmpty || !string.IsNullOrEmpty(item.Value)) values.Add(item.Value);
                    continue;
                }

                if (ignoreCase)
                {
                    var lowerItem = TextUtility.Lower(item.Key);
                    if (lowerItem == lowerArg)
                    {
                        if (withEmpty || !string.IsNullOrEmpty(item.Value)) values.Add(item.Value);
                        continue;
                    }
                }
            }
            return values.ToArray();
        }

        /// <summary>获取匹配 Key 的 Value。不存在 Key 时返回 NULL 值。</summary>
        public string GetValue(string key, bool ignoreCase = true)
        {
            if (string.IsNullOrEmpty(key)) return null;

            // 先精准匹配。
            foreach (var item in this)
            {
                if (string.IsNullOrEmpty(item.Key)) continue;
                if (item.Key == key)
                {
                    if (string.IsNullOrEmpty(item.Value)) continue;
                    return item.Value;
                }
            }

            // 再模糊匹配。
            if (ignoreCase)
            {
                var lowerArg = TextUtility.Lower(key);
                foreach (var item in this)
                {
                    if (string.IsNullOrEmpty(item.Key)) continue;
                    var lowerKey = TextUtility.Lower(item.Key);
                    if (lowerKey == lowerArg)
                    {
                        if (string.IsNullOrEmpty(item.Value)) continue;
                        return item.Value;
                    }
                }
            }

            return null;
        }

        /// <summary>设置 Key 的 Value。不存在 Key 时添加新元素。</summary>
        public void SetValue(string key, string value, bool ignoreCase = true)
        {
            if (string.IsNullOrEmpty(key)) return;

            // 先精准匹配。
            for (var i = 0; i < Count; i++)
            {
                var item = this[i];
                if (item.Key == key)
                {
                    this[i] = new KeyValuePair<string, string>(key, value);
                    return;
                }
            }

            // 再模糊匹配。
            if (ignoreCase)
            {
                var lower = TextUtility.Lower(key);
                for (var i = 0; i < Count; i++)
                {
                    var item = this[i];
                    if (TextUtility.Lower(item.Key) == lower)
                    {
                        this[i] = new KeyValuePair<string, string>(key, value);
                        return;
                    }
                }
            }

            Add(new KeyValuePair<string, string>(key, value));
        }

        /// <summary>对 Key 升序排序。</summary>
        public new void Sort()
        {
            SortAsc();
        }

        /// <summary>对 Key 升序排序。</summary>
        public void SortAsc()
        {
            base.Sort(new Comparison<KeyValuePair<string, string>>((a, b) => a.Key.CompareTo(b.Key)));
        }

        /// <summary>对 Key 降序排序。</summary>
        public void SortDesc()
        {
            base.Sort(new Comparison<KeyValuePair<string, string>>((b, a) => a.Key.CompareTo(b.Key)));
        }

        /// <summary>检查拥有指定的 Key。</summary>
        public bool HasKey(string key, bool ignoreCase = false)
        {
            var a = ignoreCase ? key.Lower() : key;
            if (string.IsNullOrEmpty(a))
            {
                foreach (var k in GetAllKeys())
                {
                    if (string.IsNullOrEmpty(k)) return true;
                }
            }
            else
            {
                foreach (var k in GetAllKeys())
                {
                    var b = ignoreCase ? k.Lower() : k;
                    if (a == b) return true;
                }
            }
            return false;
        }

        /// <summary></summary>
        public Json ToJson() => ToJson(false);

        /// <summary></summary>
        public Json ToJson(bool lowerKey)
        {
            var array = Json.NewArray();
            foreach (var pair in this)
            {
                var item = Json.NewObject();
                item[lowerKey ? "key" : "Key"] = pair.Key ?? "";
                item[lowerKey ? "value" : "Value"] = pair.Value ?? "";
                array.AddItem(item);
            }
            return array;
        }

        /// <summary>从指定对象解析，生成 StringPairs 对象实例为副本。</summary>
        public static StringPairs From(NameValueCollection collection)
        {
            var sp = new StringPairs();
            if (collection != null)
            {
                sp.Capacity = collection.Count;
                foreach (var key in collection.AllKeys)
                {
                    sp.Add(key, collection[key]);
                }
                sp.Capacity = sp.Count;
            }
            return sp;
        }

    }

}
